﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;
using Controls.Args;
using Components;
using Model.Enum;
using Model;
using System.Collections;
using System.Reflection;
using System.Drawing;

namespace Controls
{
    public class Table : TableLayoutPanel
    {
        private int _defaultWidth = 200;

        public int DefaultWidth
        {
            get { return _defaultWidth; }
            set { _defaultWidth = value; }
        }

        private string _lastVisiableColomn = "";

        /// <summary>
        /// 返回最后一个可见的控件Name,用于Medit页面最后一个控件上敲回车时，焦点进入明细控件
        /// </summary>
        public string LastVisiableColomn { get { return _lastVisiableColomn; } }

        protected Hashtable tmpValue = null; //用户在没有生成控件前就对控件进行了赋值，则将用户的值暂时储存起来。
        private List<string> CtlKeys = null; //非Lable的控件名集合

        private string bakCtlValues = null; //当前页面上所有控件的值的字符串拼接
        #region 属性

        private DataTable _dataSource;
        /// <summary>
        /// 数据源
        /// </summary>
        public DataTable DataSource
        {
            get { return _dataSource; }
            set { _dataSource = value; }
        }

        private int _rowHight = 30;

        /// <summary>
        /// 行高
        /// </summary>
        public int RowHight
        {
            get { return _rowHight; }
            set { _rowHight = value; }
        }

        private bool _autoHeight = false;

        /// <summary>
        /// 自动高度
        /// </summary>
        public bool AutoHeight
        {
            get { return _autoHeight; }
            set { _autoHeight = value; }
        }

        private int _colSize = 2;

        /// <summary>
        /// 每行的控件数 /2
        /// </summary>
        public int ColSize
        {
            get { return _colSize * 2; } //约定 Lable + 控件 才等于一个控件
            set { _colSize = value; }
        }

        private bool _isCreatedControl = false;

        /// <summary>
        /// 是否已经生成了控件
        /// </summary>
        public bool IsCreatedControl
        {
            get { return _isCreatedControl; }
        }

        #endregion

        public delegate bool DgAfterCreateLable(object sender, SummaryArgs e);
        public delegate void DgAfterCreateControl(object sender, SummaryArgs e);
        public delegate void DgAfterCheckItem(object sender, SummaryArgs e);

        /// <summary>
        /// 当创建每一个Label时触发
        /// </summary>
        public event DgAfterCreateLable AfterCreateLable;

        public event DgAfterCreateControl AfterCreateControl;

        public event DgAfterCheckItem CheckItem;

        /// <summary>
        /// 创建控件
        /// </summary>
        /// <returns></returns>
        public bool Bind(string action = null)
        {
            this.Visible = false;
            int len = DataSource.Rows.Count;
            //生成控件失败
            if (null == DataSource || 0 == len) return false;

            this.Controls.Clear();

            this.RowCount = (len % 2 == 0) ? len / _colSize : len / _colSize + 1;
            this.ColumnCount = ColSize;

            this.DoubleBuffered = true;
            DataRow dr = null;
            Label lbText = null;
            string colName = ""; //列标题
            Control c = null;
            bool IsContinueMarkControl = true; //根据生成Lable的返回值决定是否继续生成Control
            int tab = 0;
            int markColCount = 0; //生成到当前行的第几列
            int sumRowSpan = 0; //合计合并单元格
            int colSpan = 1;
            string tp;
            string tp3;

            this.SuspendLayout(); //暂时停止布局
            for (int i = 0; i < len; i++)
            {
                if (i % 2 == 0)
                {
                    this.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25F));
                }

                dr = DataSource.Rows[i]; //每一行数据
                colName = Validation.ToString(dr["colname"]);
                colSpan = Math.Max(1, Validation.ToInt(dr["colspan"]));
                tp = dr["controltype"].ToString();
                tp3 = Validation.ToString(dr["tp3"]);
                colSpan = Math.Min(this.ColSize - 1, colSpan);//1是Lable => Colspan 设置错误了，一行准不下的情况，填充成一行

                if ("y" == Validation.ToString(dr["isshow"]).ToLower()
                    || (!string.IsNullOrEmpty(tp3)
                            && !string.IsNullOrEmpty(action)
                            && tp3.IndexOf(action, System.StringComparison.Ordinal) == -1)
                ) //数据库这个字段刚好搞反了
                {
                    c = CreateItemControl(dr, null, null); //生成控件
                    c.Visible = false;
                    if (null == CtlKeys)
                    {
                        CtlKeys = new List<string>();
                    }

                    CtlKeys.Add(colName); //保存键名
                    this.Controls.Add(c);
                    continue;
                }

                //可能剩余行不够本次生成控件用,则将上一行的最后一个控件合并单元格
                if (this.ColSize - markColCount > 0 && this.ColSize - markColCount - colSpan - 1 < 0)
                {
                    if (c != null)
                    {
                        this.SetColumnSpan(c, this.ColSize - markColCount + 1);
                        markColCount = 0;
                    }
                }

                if (tp != "8") //按钮不生成Lable
                {
                    //生成Lable
                    lbText = new Label();
                    lbText.Name = "lb" + colName;
                    lbText.Text = Validation.ToString(dr["headcn"]) + "：";
                    lbText.Dock = DockStyle.Top;
                    lbText.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
                    IsContinueMarkControl = OnAfterCreateLable(lbText, new SummaryArgs(colName, dr)); //触发生成lable的事件
                    this.Controls.Add(lbText);//添加控件集合
                    sumRowSpan++;
                    markColCount++;
                }

                //生成控件
                c = CreateItemControl(dr, null, null); //生成控件
                if (null == CtlKeys)
                {
                    CtlKeys = new List<string>();
                }

                CtlKeys.Add(colName); //保存键名

                OnAfterCreateControl(c, new SummaryArgs(colName, dr)); //触发生成Control的事件
                if (!IsContinueMarkControl) c.Visible = false;
                c.TabIndex = tab++;
                c.Width = (0 == Validation.ToInt(dr["columnwidth"]) ? DefaultWidth : c.Width);
                sumRowSpan += colSpan;
                markColCount += colSpan;
                if (colSpan > 1) this.SetColumnSpan(c, colSpan);

                if (c.Visible == true) //记录最后一个显示的控件
                {
                    _lastVisiableColomn = colName;
                }

                this.Controls.Add(c); //添加控件集合
                if (this.ColSize - markColCount == 0) markColCount = 0;
            }

            this.RowCount = (sumRowSpan % this.ColSize == 0) ? sumRowSpan / this.ColSize : sumRowSpan / this.ColSize + 1;

            //FormatStyle();
            this.ResumeLayout(); //恢复布局

            _isCreatedControl = true; // 更新生成标志
            this.Visible = true;
            return true;
        }

        protected virtual bool OnAfterCreateLable(object source, SummaryArgs args)
        {
            if (this.AfterCreateLable != null) { return this.AfterCreateLable(source, args); } //调用事件
            return true;
        }

        protected virtual void OnAfterCreateControl(object source, SummaryArgs args)
        {
            if (this.AfterCreateControl != null) { this.AfterCreateControl(source, args); } //调用事件
        }

        protected virtual void OnCheckItem(object source, SummaryArgs args)
        {
            if (this.CheckItem != null) { this.CheckItem(source, args); } //调用事件
        }

        /// <summary>
        /// 创建控件
        /// </summary>
        /// <param name="drData">控件数据</param>
        /// <param name="value">值，如果是普通控件，value代表控件的Text,popWin的时候，value是popWin的Value</param>
        /// <param name="desc">仅popWin时有用</param>
        private Control CreateItemControl(DataRow dr, string value, string desc)
        {
            string tp = dr["controltype"].ToString();
            string cn = dr["colname"].ToString();
            string dp = dr["headcn"].ToString();
            string md = (dr["editmode"] is DBNull) ? "" : dr["editmode"].ToString(); //可编辑模式
            string def = (dr["defvalue"] is DBNull) ? "" : dr["defvalue"].ToString();
            int maxLength = (dr["maxlength"] is DBNull) ? 0 : Convert.ToInt32(dr["maxlength"]);
            string param = (dr["columnparam"] is DBNull) ? "" : dr["columnparam"].ToString();
            string option = (dr["columnoption"] is DBNull) ? "" : dr["columnoption"].ToString();
            int width = Validation.ToInt(dr["columnwidth"]);
            string fmt = (dr["fmt"] is DBNull) ? "" : dr["fmt"].ToString();//格式化字符串
            PsDataType tpy = (PsDataType)Convert.ToInt32(dr["coltype"]); //数据类型
            bool notnull = ("Y" == dr["notnull"].ToString());
            string tp5 = Validation.ToString(dr["tp6"]); //是否保存原值
            bool isKeepValue = (!string.IsNullOrEmpty(tp5) && "Y" == tp5.ToUpper());
            Label lbErrorText = null; //输出错误信息
            string tmp = "";
            string[] tmpArr = null;
            object val = (null == this.tmpValue || !this.tmpValue.ContainsKey(cn)) ? def : this.tmpValue[cn];
            string tp3 = Validation.ToString(dr["tp3"]);

            switch (tp)
            {
                case "0": //Radio
                    if (string.IsNullOrEmpty(option))
                    {
                        lbErrorText = new Label(); //输出错误信息
                        lbErrorText.Text = "未设置Radio的Option！";
                        return lbErrorText;
                    }

                    PsFlowLayoutPanel p = new PsFlowLayoutPanel();
                    p.EditMode = md;
                    p.Dock = DockStyle.Top;
                    p.Lable = dp;
                    p.IsRequie = notnull;
                    p.Name = cn;
                    p.DefaultValue = def;
                    p.FlowDirection = FlowDirection.LeftToRight;
                    p.IsKeepFonValue = isKeepValue;
                    p.DisplayMode = tp3;

                    string[] ops = option.Split(',');
                    string[] cp = null;
                    RadioButton radio = null;
                    foreach (string o in ops)
                    {
                        radio = new RadioButton();
                        cp = o.Split('|');
                        radio.Name = cp[0];
                        radio.AutoSize = true;
                        radio.Text = cp.Length > 1 ? cp[1] : cp[0];
                        if (null != val && radio.Name == val.ToString()) radio.Checked = true; //设置默认值

                        radio.KeyDown += new KeyEventHandler(delegate { SendKeys.Send("{Tab}"); });
                        p.Controls.Add(radio); //将Radio加入PsFlowLayoutPanel
                    }
                    return p;
                case "1"://CheckBox
                    if (string.IsNullOrEmpty(option))
                    {
                        lbErrorText = new Label(); //输出错误信息
                        lbErrorText.Text = "未设置CheckBox的Option！";
                        return lbErrorText;
                    }
                    PsCheckBox chk = new PsCheckBox();
                    chk.Name = cn;
                    chk.EditMode = md;
                    tmpArr = option.Split('|');
                    chk.CheckedValue = tmpArr[0];
                    chk.DefaultValue = def;
                    chk.IsKeepFonValue = isKeepValue;
                    chk.UnCheckedValue = tmpArr.Length > 1 ? tmpArr[1] : "N";//默认未选中时候的代码时候N
                    chk.Checked = (null != val && chk.CheckedValue.ToString() == val.ToString()); //设置默认值
                    chk.DisplayMode = tp3;

                    return chk;
                case "2"://PopWin
                    tmp = (dr["tp2"] is DBNull) ? "" : dr["tp2"].ToString(); //临时变量2
                    if (string.IsNullOrEmpty(tmp))
                    {
                        lbErrorText = new Label(); //输出错误信息
                        lbErrorText.Text = "未能设置弹出框的PopKey！";
                        return lbErrorText;
                    }

                    PsPopWin popWin = new PsPopWin();
                    popWin.Name = cn;
                    popWin.EditMode = md;
                    popWin.MaxLength = maxLength;
                    popWin.Lable = dp;
                    popWin.IsRequie = notnull;
                    popWin.PopKey = tmp;
                    popWin.DbType = tpy;
                    popWin.DefaultValue = def;
                    popWin.IsKeepFonValue = isKeepValue;
                    popWin.DisplayMode = tp3;
                    if (0 != width) popWin.Width = width;

                    if (val is object[])
                    {
                        object[] newVal = val as object[];
                        if (newVal.Length == 0) return popWin;
                        popWin.Value = newVal[0].ToString();
                        popWin.Text = newVal.Length > 1 ? newVal[1].ToString() : newVal[0].ToString();
                    }
                    else if (null != val)
                    {
                        popWin.Value = popWin.Text = val.ToString();
                    }

                    return popWin;
                case "3"://Text
                case "4"://TextArea
                case "6"://Password
                    if (tpy == PsDataType.Date || tpy == PsDataType.Datetime)
                    {
                        PsDatePicker pdp = new PsDatePicker();
                        pdp.Name = cn;
                        pdp.EditMode = md;
                        pdp.IsRequie = notnull;
                        pdp.IsKeepFonValue = isKeepValue;
                        pdp.DisplayMode = tp3;
                        if (0 != width) pdp.Width = width;
                        if (!pdp.IsRequie) //如果日期控件不是必填，日期选择框显示复选框
                        {
                            pdp.ShowCheckBox = true;
                        }

                        if (tpy == PsDataType.Date)
                        {
                            pdp.CustomFormat = "yyyy-MM-dd";
                            pdp.Format = DateTimePickerFormat.Custom;
                        }
                        else if (!string.IsNullOrEmpty(fmt))
                        {
                            pdp.CustomFormat = fmt;
                            pdp.Format = DateTimePickerFormat.Custom;
                        }

                        pdp.DefaultValue = def;
                        if (val is DateTime) pdp.Value = Convert.ToDateTime(val);
                        else if (null != val) pdp.Text = val.ToString();

                        if (string.IsNullOrEmpty(pdp.Text))
                        {
                            pdp.Checked = false;
                        }

                        return pdp;
                    }
                    else //普通文本框或文本域
                    {
                        PsTextBox t1 = new PsTextBox();
                        t1.Name = cn;
                        t1.Lable = dp;
                        t1.IsRequie = notnull;
                        t1.DisplayMode = tp3;
                        if (0 != width) t1.Width = width;
                        if ("4" == tp) //文本域
                        {
                            t1.Multiline = true;
                            t1.Height = 130;
                            //t1.Dock = DockStyle.Fill;
                        }
                        else if ("6" == tp) //password
                        {
                            t1.PasswordChar = '*';
                        }
                        t1.EditMode = md;
                        t1.DbType = tpy;
                        t1.FormatString = fmt;
                        t1.MaxLength = maxLength;
                        t1.DefaultValue = def;
                        if (!(dr["tp1"] is DBNull) && "1" == dr["tp1"].ToString()) //系统设置只读
                        {
                            t1.SysReadOnly = true;
                            t1.Enabled = false;
                        }

                        if (t1.DbType == PsDataType.Int || t1.DbType == PsDataType.IntThanZero || t1.DbType == PsDataType.IntThanZeroOrEqualZero
                            || t1.DbType == PsDataType.Num || t1.DbType == PsDataType.NumThanZero || t1.DbType == PsDataType.NumThanZeroOrEqualZero)
                        {
                            t1.TextAlign = HorizontalAlignment.Right;
                        }

                        t1.IsKeepFonValue = isKeepValue;
                        t1.Text = val.ToString();
                        return t1;
                    }
                case "5"://Select
                    PsSelect slt = new PsSelect();
                    slt.Name = cn;
                    slt.EditMode = md;
                    slt.DropDownStyle = ComboBoxStyle.DropDownList;
                    slt.Lable = dp;
                    slt.IsRequie = notnull;
                    slt.DefaultValue = def;
                    slt.IsKeepFonValue = isKeepValue;
                    slt.DisplayMode = tp3;

                    if (0 != width) slt.Width = width;

                    if (!(dr["tp1"] is DBNull) && "1" == dr["tp1"].ToString()) //系统设置只读
                    {
                        slt.SysReadOnly = true;
                        slt.Enabled = false;
                    }

                    string[] oslt = option.Split(',');
                    string[] cpslt = null;
                    int count = -1;
                    int i = 0;
                    foreach (string o in oslt)
                    {
                        cpslt = o.Split('|');
                        if (null != val && cpslt[0] == val.ToString()) count = i;
                        slt.Items.Add(new TextValuePair(cpslt.Length > 1 ? cpslt[1] : cpslt[0], cpslt[0]));
                        i++;
                    }
                    if (-1 != count) slt.SelectedIndex = count; //设置默认值
                    return slt;
                case "7"://File
                    PsFile file = new PsFile();
                    file.Name = cn;
                    file.EditMode = md;
                    file.IsRequie = notnull;
                    if (0 != width) file.Width = width;
                    file.Text = file.Lable = dp;
                    file.BackColor = Color.AliceBlue;
                    file.DisplayMode = tp3;
                    return file;
                case "8"://Button
                    PsButton btn = new PsButton();
                    btn.Name = cn;
                    btn.EditMode = md;
                    btn.IsRequie = notnull;
                    if (0 != width) btn.Width = width;
                    btn.Text = btn.Lable = dp;
                    btn.BackColor = Color.AliceBlue;
                    btn.DisplayMode = tp3;
                    return btn;
                case "9": //Hidden
                    break;
            }

            return null;
        }

        public void FormatStyle()
        {
            if (this.ColumnCount == 0 || this.RowCount == 0) return;

            this.SuspendLayout(); //暂时停止布局

            int widthHeight = (int)((this.ClientSize.Width - 10) / this.ColumnCount); //20是边框宽度 + 由于文字右对齐，所以造成最左边的一列很宽
            int height = AutoHeight ? RowHight : (int)(this.Height / this.RowCount);
            //this.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;

            for (int i = 0; i < this.ColumnCount; i++)
            {
                if (this.ColumnStyles.Count > i)
                {
                    this.ColumnStyles[i].SizeType = SizeType.Absolute;
                    this.ColumnStyles[i].Width = widthHeight;
                }
                else
                {
                    this.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, widthHeight));
                }
            }

            for (int i = 0; i < this.RowStyles.Count; i++)
            {
                this.RowStyles[i].SizeType = SizeType.Absolute;
                this.RowStyles[i].Height = height;
            }

            if (AutoHeight) this.Height = RowHight * this.RowCount + 20;//自动计算整体高度 20是由一个小空隙

            this.ResumeLayout();

            this.Refresh();
        }

        /// <summary>
        /// 给控件赋值
        /// </summary>
        /// <param name="ctlName">控件名称</param>
        /// <param name="value">值，如果是普通控件，value代表控件的Text,popWin的时候，value是popWin的Value, 仅popWin时有用第二个参数</param>
        /// <param name="desc"></param>
        public void SetValue(string ctlName, params object[] _value)
        {
            if (IsCreatedControl) //已经创建过控件了，那就只能通过FindControl去找了
            {
                this._setValue(ctlName, _value);
            }
            else
            {
                if (null == this.tmpValue)
                {
                    tmpValue = new Hashtable();
                }

                tmpValue[ctlName] = _value; //暂时先存储起来
            }
        }

        /// <summary>
        /// 给概要控件批量赋值 , 默认只会取DataTable中的第一行数据
        /// </summary>
        /// <param name="hsData"></param>
        public void Fill(DataTable dtData)
        {
            if (null == dtData || dtData.Rows.Count == 0) return;

            DataRow dr = dtData.Rows[0];

            DataColumnCollection dcc = dtData.Columns;
            object desc = null;
            foreach (DataColumn col in dcc)
            {
                if (dcc.Contains(col.ColumnName + "_desc")) desc = dr[col.ColumnName + "_desc"]; //供弹出框加描述用
                this.SetValue(col.ColumnName, dr[col.ColumnName], desc);
            }
        }

        /// <summary>
        /// 根据实体的值自动填充控件
        /// </summary>
        /// <param name="objModel"></param>
        public void Fill(object objModel)
        {
            Type oType = objModel.GetType();
            PropertyInfo[] propertys = oType.GetProperties();

            string name = "";
            foreach (PropertyInfo info in propertys)
            {
                name = info.Name.ToLower();
                if (!this.Controls.ContainsKey(name)) continue;

                this.SetValue(name, info.GetValue(objModel, null));
            }
        }

        /// <summary>
        /// 根据控件值，自动填充实体
        /// </summary>
        /// <param name="o"></param>
        public void Drain(object o)
        {
            Type oType = o.GetType();
            PropertyInfo[] propertys = oType.GetProperties();

            string name = "";
            Control c = null;
            object tv = null;
            foreach (PropertyInfo info in propertys)
            {
                name = info.Name.ToLower();
                if (!this.Controls.ContainsKey(name)) continue;

                c = this.Controls[name];
                tv = _getValue(c); //获得控件的值

                _addValue(info, tv, o);
            }
        }

        /// <summary>
        /// 向属性中添加对应类型的值
        /// </summary>
        /// <param name="info">属性对象</param>
        /// <param name="Value">值</param>
        /// <param name="obj">属性所属对象</param>
        /// <param name="hasKey">Request对象中是否有该属性</param>
        private void _addValue(PropertyInfo info, object value, Object obj)
        {
            if (null == value) //如果是空
            {
                info.SetValue(obj, null, null);
                return;
            }
            if (info.PropertyType == typeof(String))
            {
                info.SetValue(obj, value, null);
            }
            else if (info.PropertyType == typeof(int?) || info.PropertyType == typeof(int))
            {
                info.SetValue(obj, Convert.ToInt32(value), null);
            }
            else if (info.PropertyType == typeof(DateTime?) || info.PropertyType == typeof(DateTime))
            {
                info.SetValue(obj, Convert.ToDateTime(value), null);
            }
            else if (info.PropertyType == typeof(Decimal?) || info.PropertyType == typeof(Decimal))
            {
                info.SetValue(obj, Convert.ToDecimal(value), null);
            }
            else if (info.PropertyType == typeof(Double?) || info.PropertyType == typeof(Double))
            {
                info.SetValue(obj, Convert.ToDouble(value), null);
            }
            else if (info.PropertyType == typeof(float?) || info.PropertyType == typeof(float))
            {
                info.SetValue(obj, Convert.ToDecimal(value), null);
            }
            else if (info.PropertyType == typeof(bool?) || info.PropertyType == typeof(bool))
            {
                info.SetValue(obj, (value.ToString() != "0"), null);
            }
        }

        /// <summary>
        /// 得到控件的值，本例子中只有两种控件，故先这样写
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        private object _getValue(Control c)
        {
            if (null == c) return null;
            TextValuePair tpl = null;

            if (c is PsPopWin)
            {
                PsPopWin pop = c as PsPopWin;
                //弹出框如果设置了Value，则返回Value，否则返回Text
                return (null == pop) ? null : (string.IsNullOrEmpty(pop.Value) ? pop.Text : pop.Value);
            }
            else if (c is PsTextBox)
            {
                TextBox txt = c as TextBox;
                return (null == txt) ? null : txt.Text;
            }
            else if (c is DateTimePicker)
            {
                DateTimePicker dp = c as DateTimePicker;
                return (null == dp || (dp.ShowCheckBox && !dp.Checked)) ? null : dp.Value.ToString(dp.CustomFormat);
            }
            else if (c is PsSelect)
            {
                PsSelect sls = c as PsSelect;
                if (sls == null) return null;
                tpl = sls.SelectedItem as TextValuePair;
                if (tpl == null) return null;
                return tpl.Value;
            }
            else if (c is PsFlowLayoutPanel)
            {
                PsFlowLayoutPanel fp = c as PsFlowLayoutPanel;
                if (fp == null || fp.Controls.Count == 0) return null;
                foreach (Control ccl in fp.Controls)
                {
                    if (ccl is RadioButton && ((RadioButton)ccl).Checked) return ccl.Name;
                }
            }
            else if (c is PsCheckBox)
            {
                PsCheckBox chk = c as PsCheckBox;
                if (null == chk) return null;
                return chk.Checked ? chk.CheckedValue : chk.UnCheckedValue;
            }
            else if (c is PsFile)
            {
                PsFile file = c as PsFile;
                return (null == file) ? null : file.FilePath;
            }
            return null;
        }

        /// <summary>
        /// 根据控件名称设置控件的值
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        private void _setValue(string name, object[] _v)
        {
            if (null == _v || _v.Length == 0) return;

            object value = _v[0];
            if (null == value) return;

            if (!this.Controls.ContainsKey(name)) return; //可能键名错误
            Control c = this.Controls[name];
            if (c is PsPopWin)
            {
                PsPopWin pop = c as PsPopWin;
                pop.Text = value.ToString();
                pop.Value = (_v.Length > 1) ? Validation.ToString(_v[1]) : pop.Text;
            }
            else if (c is TextBox)
            {
                TextBox txt = c as TextBox;
                txt.Text = value.ToString();
            }
            else if (c is PsSelect)
            {
                PsSelect drp = c as PsSelect;
                if (drp == null) return;
                drp.SelectedItem = value;
            }
            else if (c is PsFlowLayoutPanel) //RadioButton
            {
                PsFlowLayoutPanel drp = c as PsFlowLayoutPanel;
                if (drp == null || 0 == drp.Controls.Count) return;
                foreach (Control cctl in drp.Controls)
                {
                    if (cctl is RadioButton && cctl.Name == Validation.ToString(value))
                    {
                        ((RadioButton)cctl).Checked = true;
                    }
                }
            }
            else if (c is CheckBox)
            {
                CheckBox cbk = c as CheckBox;
                if (cbk == null) return;
                if (value is string)
                {
                    string sv = null == value ? "" : value.ToString();
                    cbk.Checked = ("Y" == sv || "TRUE" == sv);
                }
                else if (value is Int32)
                {
                    cbk.Checked = 0 != Convert.ToInt32(value);
                }
                else if (value is Boolean)
                {
                    cbk.Checked = Convert.ToBoolean(value);
                }
                else
                    cbk.Checked = false;
            }
            else if (c is PsDatePicker)
            {
                PsDatePicker ps = c as PsDatePicker;
                if (ps == null) return;

                ps.Checked = !(ps.ShowCheckBox && Validation.IsNull(value));

                if (value is string)
                {
                    ps.Text = value.ToString();
                }
                else if (value is DateTime)
                {
                    ps.Value = Convert.ToDateTime(value);
                }
            }
            else if (c is PsFile)
            {
                PsFile file = c as PsFile;
                file.FilePath = Validation.ToString(value);
            }
        }

        /// <summary>
        /// 设置控件状态
        /// </summary>
        /// <param name="actionMode"></param>
        public void SetControlState(string actionMode)
        {
            TableLayoutControlCollection ctls = this.Controls;
            if (null == ctls || 0 == ctls.Count) return;

            var willDelList = new List<string>();
            foreach (Control c in ctls)
            {
                if (c is PsTextBox)
                {
                    PsTextBox txt = c as PsTextBox;
                    if (txt.SysReadOnly) { txt.ReadOnly = true; continue; }
                    txt.Enabled = (null != txt.EditMode && (txt.EditMode.IndexOf(actionMode) > -1));

                    _setLastControlName(txt);
                }
                else if (c is PsPopWin)
                {
                    PsPopWin pop = c as PsPopWin;
                    if (pop.SysReadOnly) { pop.Enabled = false; continue; }
                    pop.Enabled = (null != pop.EditMode && (pop.EditMode.IndexOf(actionMode) > -1));

                    _setLastControlName(pop);
                }
                else if (c is PsDatePicker)
                {
                    PsDatePicker pdp = c as PsDatePicker;
                    if (pdp.SysReadOnly) { pdp.Enabled = false; continue; }
                    pdp.Enabled = (null != pdp.EditMode && (pdp.EditMode.IndexOf(actionMode, System.StringComparison.Ordinal) > -1));

                    _setLastControlName(pdp);
                }
                else if (c is PsSelect)
                {
                    PsSelect sls = c as PsSelect;
                    if (sls.SysReadOnly) { sls.Enabled = false; continue; }
                    sls.Enabled = (null != sls.EditMode && (sls.EditMode.IndexOf(actionMode, System.StringComparison.Ordinal) > -1));

                    _setLastControlName(sls);
                }
                else if (c is PsFlowLayoutPanel) //RadioButton
                {
                    PsFlowLayoutPanel sls = c as PsFlowLayoutPanel;
                    if (sls.SysReadOnly) { sls.Enabled = false; continue; }
                    sls.Enabled = (null != sls.EditMode && (sls.EditMode.IndexOf(actionMode, System.StringComparison.Ordinal) > -1));

                    _setLastControlName(sls);
                }
                else if (c is PsButton)
                {
                    PsButton btn = c as PsButton;
                    if (btn.SysReadOnly) { btn.Enabled = false; continue; }
                    btn.Enabled = (null != btn.EditMode && (btn.EditMode.IndexOf(actionMode, System.StringComparison.Ordinal) > -1));

                    _setLastControlName(btn);
                }
                else if (c is PsFile)
                {
                    PsFile file = c as PsFile;
                    if (file.SysReadOnly) { file.Enabled = false; continue; }
                    file.Enabled = (null != file.EditMode && (file.EditMode.IndexOf(actionMode, System.StringComparison.Ordinal) > -1));

                    _setLastControlName(file);
                }
            }

            foreach (var name in willDelList)
            {
                //由于将控件隐藏，隐藏的控件依然会占据位置，所以
                RemoveItem(name);
            }
        }

        void _setLastControlName(Control c)
        {
            if (c == null || c.Enabled == false || c.Visible == false) return;

            _lastVisiableColomn = c.Name;
        }

        /// <summary>
        /// 检测控件
        /// </summary>
        /// <returns></returns>
        public string CheckSelf()
        {
            if (null == this.CtlKeys) return "";

            this.Focus(); //结束当前页面的编辑状态
            Control c = null;
            TextBoxX txt = null;
            PsFlowLayoutPanel fp = null;
            RadioButton radio = null;
            PsSelect drp = null;
            PsDatePicker pdp = null;
            TextValuePair p = null;
            PsFile file = null;
            bool find = false;
            string errmsg = "";
            foreach (string ctl in this.CtlKeys)
            {
                if (!this.Controls.ContainsKey(ctl)) continue;

                c = this.Controls[ctl];

                if (c is TextBoxX)
                {
                    txt = c as TextBoxX;
                    if (txt.IsRequie && string.IsNullOrEmpty(txt.Text))//检测必填
                    {
                        txt.Focus();
                        return string.Format("【{0}】不能为空！", txt.Lable);
                    }
                    if (!string.IsNullOrEmpty(txt.Text))
                    {
                        errmsg = UIValidation.Validate(txt.DbType, txt.Text);
                        if (!string.IsNullOrEmpty(errmsg)) return string.Format("【{0}】{1}！", txt.Lable, errmsg);
                    }
                    OnCheckItem(txt, new SummaryArgs(txt.Name, txt.Text));
                }
                else if (c is PsFlowLayoutPanel)
                {
                    fp = c as PsFlowLayoutPanel;

                    if (txt.IsRequie) //检测必填
                    {
                        if (fp.Controls.Count == 0) return string.Format("【{0}】不能为空！", fp.Lable);
                        find = false;
                        foreach (Control ccl in fp.Controls)
                        {
                            radio = ccl as RadioButton;
                            if (radio.Checked)
                            {
                                find = true;
                                break;
                            }
                        }

                        if (!find) return string.Format("【{0}】不能为空！", fp.Lable);
                    }
                }
                else if (c is PsSelect)
                {
                    drp = c as PsSelect;
                    p = drp.SelectedItem as TextValuePair;
                    if (drp.IsRequie && p == null)
                    {
                        drp.Focus();
                        return string.Format("【{0}】不能为空！", drp.Lable);
                    }
                }
                else if (c is PsFile)
                {
                    file = c as PsFile;
                    if (file.IsRequie && Validation.IsNull(file.FilePath))
                    {
                        file.Focus();
                        return string.Format("【{0}】不能为空！", file.Lable);
                    }
                }
            }
            return "";
        }

        /// <summary>
        /// 得到得到所有值
        /// </summary>
        /// <returns></returns>
        public Hashtable GetAllValue()
        {
            if (this.CtlKeys == null) return null;

            Control c = null;
            Hashtable hs = null;
            foreach (string ctl in CtlKeys)
            {
                if (!this.Controls.ContainsKey(ctl)) continue;

                c = this.Controls[ctl];
                if (null == hs)
                {
                    hs = new Hashtable();
                }

                hs[c.Name] = _getValue(c);
            }

            return hs;
        }

        /// <summary>
        /// 获得控件的值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object GetValue(string name)
        {
            if (!this.Controls.ContainsKey(name)) return null;
            Control c = this.Controls[name];

            return _getValue(c);
        }

        public void Focus(string name)
        {
            if (!this.Controls.ContainsKey(name)) return;
            Control c = this.Controls[name];
            c.Focus();
        }

        /// <summary>
        /// 让界面的第一个控件的到焦点
        /// </summary>
        public void FocusFirst()
        {
            if (this.CtlKeys == null) return;

            Control c = null;
            foreach (string ctl in CtlKeys)
            {
                if (!this.Controls.ContainsKey(ctl)) continue;

                c = this.Controls[ctl];
                if (c.Visible == false) continue;

                c.Focus();
                break;
            }
        }

        public void Clear()
        {
            foreach (Control c in this.Controls)
            {
                ClearItem(c.Name);
            }
        }

        public void SetRequie(string name, bool isRequie)
        {
            if (!this.Controls.ContainsKey(name)) return; //可能键名错误
            Control c = this.Controls[name];
            if (c is PsPopWin)
            {
                PsPopWin pop = c as PsPopWin;
                pop.IsRequie = isRequie;
            }
            else if (c is TextBoxX)
            {
                TextBoxX txt = c as TextBoxX;
                txt.IsRequie = isRequie;
            }
            else if (c is PsSelect)
            {
                PsSelect drp = c as PsSelect;
                drp.IsRequie = isRequie;
            }
            else if (c is PsDatePicker)
            {
                PsDatePicker ps = c as PsDatePicker;
                ps.IsRequie = isRequie;
            }
            else if (c is PsFile)
            {
                PsFile file = c as PsFile;
                file.IsRequie = isRequie;
            }
        }

        public void Enable(string name, bool isEnable)
        {
            if (!this.Controls.ContainsKey(name)) return; //可能键名错误
            Control c = this.Controls[name];
            c.Enabled = isEnable;
        }

        public bool IsEnabled(string name)
        {
            if (!this.Controls.ContainsKey(name)) return false; //可能键名错误
            Control c = this.Controls[name];
            return c.Enabled;
        }

        /// <summary>
        /// 保存备份，用户检测控件整体是否被修改，节约带宽
        /// </summary>
        public void SaveBak()
        {
            bakCtlValues = GetNowValueString();
        }

        /// <summary>
        /// 检测值是否改变
        /// </summary>
        /// <returns></returns>
        public bool IsModify()
        {
            string now = GetNowValueString();
            return now != bakCtlValues;
        }

        private string GetNowValueString()
        {
            if (this.CtlKeys == null) return null;

            Control c = null;
            StringBuilder sb = new StringBuilder();
            foreach (string ctl in CtlKeys)
            {
                if (!this.Controls.ContainsKey(ctl)) continue;

                c = this.Controls[ctl];
                if (0 != sb.Length) sb.Append(",");

                sb.Append(_getValue(c));
            }

            return sb.ToString();
        }

        /// <summary>
        /// 设置控件的现实或隐藏
        /// </summary>
        /// <param name="colName"></param>
        /// <param name="isShow"></param>
        public void Show(string colName, bool isShow)
        {
            if (!this.Controls.ContainsKey(colName)) return;

            this.Controls[colName].Visible = isShow;
            var labelControls = this.Controls.Find("lb" + colName, false);
            if (labelControls.Length > 0)
                labelControls[0].Visible = isShow; //标题
        }

        public void RemoveItem(string colName)
        {
            if (!this.Controls.ContainsKey(colName)) return;

            this.Controls.RemoveByKey(colName);
            var labelControls = this.Controls.Find("lb" + colName, false);
            if (labelControls.Length > 0)
                this.Controls.Remove(labelControls[0]); //标题
        }

        public void ClearItem(string name)
        {
            if (!this.Controls.ContainsKey(name)) return; //可能键名错误
            Control c = this.Controls[name];
            if (c is PsPopWin)
            {
                PsPopWin pop = c as PsPopWin;
                if (pop.IsKeepFonValue) return;
                pop.Text = pop.DefaultValue;
                pop.Value = "";
            }
            else if (c is TextBoxX)
            {
                TextBoxX txt = c as TextBoxX;
                if (txt.IsKeepFonValue) return;
                txt.Text = txt.DefaultValue;
            }
            else if (c is PsSelect)
            {
                PsSelect drp = c as PsSelect;
                if (drp.IsKeepFonValue) return;
                drp.SelectedIndex = 0;
            }
            else if (c is PsFlowLayoutPanel) //RadioButton
            {
                PsFlowLayoutPanel drp = c as PsFlowLayoutPanel;
                if (drp == null || 0 == drp.Controls.Count) return;
                if (drp.IsKeepFonValue) return;
                foreach (Control cctl in drp.Controls)
                {
                    if (cctl.Name == drp.DefaultValue)
                        ((RadioButton)cctl).Checked = true;
                }
            }
            else if (c is PsCheckBox)
            {
                PsCheckBox cbk = c as PsCheckBox;
                if (cbk == null) return;
                if (cbk.IsKeepFonValue) return;
                cbk.Checked = (((cbk.CheckedValue == null) ? "" : cbk.CheckedValue.ToString()) == cbk.DefaultValue);
            }
            else if (c is PsDatePicker)
            {
                PsDatePicker ps = c as PsDatePicker;
                if (ps.IsKeepFonValue) return;
                if (ps.ShowCheckBox)
                {
                    if (string.IsNullOrEmpty(ps.DefaultValue))
                    {
                        ps.Checked = false;
                    }
                    else
                    {
                        ps.Checked = true;
                        ps.Value = Convert.ToDateTime(ps.DefaultValue);
                    }

                    return;
                }

                if (string.IsNullOrEmpty(ps.DefaultValue))
                    ps.Value = DateTime.Now;
                else
                    ps.Value = Convert.ToDateTime(ps.DefaultValue);
            }
            else if (c is PsFile)
            {
                PsFile file = c as PsFile;
                if (null == file) return;
                file.FilePath = "";
            }
        }
    }
}
